﻿ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
//using GlobalGame;
using WindowsGame3;

namespace WindowsGame1
{
    class SpriteAnimation
    {
        public Rectangle rect;
        Texture2D idle;
        Texture2D run;
        Texture2D kill;
        Texture2D down;
        Texture2D killrun;
        Texture2D killdown;
        Texture2D jump;
        public Vector2 Pos;

        Game1 game;

        public bool isrunning;//герой іде чи нейде
        public bool RunLeft;//рух вілво або право
        public bool isStopLeft;// зупинка вліво
        public bool iskillup;//стрільба стоячи
        public bool KillUpLeft;//стрільба стоячи вліво
        public bool isdown;//присідання
        public bool downleft;//присідання вліво
        public bool iskillrun;//стрільба рухаючись
        public bool KillRunLeft;//стрільба рухаючись вліво
        public bool iskilldown;//стрільба в присіданні
        public bool KillDownLeft;//стрільба в присіданні вліво
        public bool isjumping;//прижок
        public bool JumpLeft;//прижок вліво

        public float yVelocity;//швидкість пригання
        public float maxYVelocity = 10;//максимальне значення висоти прижка
        public float g = 0.15f;//прискорення вільного падіння

        public int framewidth;// ширина кожного кадру анімації
        public int frameheight;// вислота кожного кадру анімації

        int currentframe;// номер поточного кадру
        int elapsedtime;// час на показ всього спрайту
        int timeforframe = 90;// час на показ одного кадру анімації

        // Метод для визначення кількості фреймів в спрайті коли герой іде
        public int FramesRun
        {
            get
            {
                return run.Width / framewidth;
            }
        }
        //Метод для визначення кількості фреймів в спрайті коли герой стріляє стоячи
        public int FramesKill
        {
            get
            {
                return kill.Width / framewidth;
            }
        }
       // Метод для визначення кількості фреймів в спрайті коли герой присідає
        public int FramesDown
        {
            get
            {
                return down.Width / framewidth;
            }
        }
        //Метод для визначення кількості фреймів в спрайті коли герой іде стріляючи
        public int FramesKillRun
        {
            get
            {
                return killrun.Width / framewidth;
            }
        }
        //Метод для визначення кількості фреймів в спрайті коли герой стріляє сидячи
        public int FramesKillDown
        {
            get
            {
                return killdown.Width / framewidth;
            }
        }
        //метод для визначення фреймів в спрайті коли герой пригає
        public int FramesJump
        {
            get 
            {
                return jump.Width / framewidth;
            }
        }
        //Конструктор для основних текстур анімації
        public SpriteAnimation(Rectangle rect, Texture2D idle, Texture2D run, Texture2D kill,Texture2D down,Texture2D killrun,Texture2D killdown, Texture2D jump ,Game1 game)
        {
            this.rect = rect;
            this.idle = idle;
            this.run = run;
            this.kill = kill;
            this.down = down;
            this.killrun = killrun;
            this.killdown = killdown;
            this.jump = jump;
            this.game = game;

            framewidth = 160;
            frameheight = run.Height;
        }
        //Метод оновлення кадрів кожного спрайту анімації і сама анімація для кожної текстури
        public void Update(GameTime gametime)
        {
            //герой іде
            if (isrunning)
            {
                elapsedtime += gametime.ElapsedGameTime.Milliseconds;
            }
            if (elapsedtime > timeforframe)
            {
                currentframe = (currentframe +1) % FramesRun;
                elapsedtime = 0;
            }
            //герой стоячи стріляє
            if (iskillup)
            {
                elapsedtime += gametime.ElapsedGameTime.Milliseconds;
            }
            if (elapsedtime > timeforframe)
            {
                currentframe = (currentframe + 1) % FramesKill;
                elapsedtime = 0;
            }
            //герой присідає
            if (isdown)
            {
                elapsedtime +=gametime.ElapsedGameTime.Milliseconds*2;
            }
            if (elapsedtime > timeforframe)
            {
                currentframe ++;
                if (currentframe == FramesDown)
                    currentframe = 4;
                elapsedtime = 0;
            }
            //герой іде стріляючи
            if (iskillrun)
            {
                elapsedtime += gametime.ElapsedGameTime.Milliseconds;
            }
            if (elapsedtime > timeforframe)
            {
                currentframe = (currentframe + 1) % FramesKillRun;
                elapsedtime = 0;
            }
            //герой в присідання стріляє
            if (iskilldown)
            {
                elapsedtime += gametime.ElapsedGameTime.Milliseconds/10;
            }
            if (elapsedtime > timeforframe)
            {
                currentframe = (currentframe + 1) % FramesKillDown;
                elapsedtime = 0;
            }
            if (isjumping)
            {
                elapsedtime += gametime.ElapsedGameTime.Milliseconds / 10 ;
            }
            if (elapsedtime > timeforframe)
            {
                currentframe =(currentframe + 1) % FramesJump;
                elapsedtime = 0;
            }
            // Рух героя вліво і право
            int dx =  gametime.ElapsedGameTime.Milliseconds/4;
            if (!isrunning && !iskillrun)
            {
                dx = 0;
            }
            if (RunLeft)
            {
                dx = -dx;
            }
            Rectangle nextposition = rect;
            nextposition.Offset(dx,0);
            Rectangle boundingrect = GetBoundingRect(nextposition);
            Rectangle screenRect = Game1.GetScreenRect(boundingrect);
            if (screenRect.Left > 0 && screenRect.Right < game.width && !game.ColidesWithLevel(boundingrect))
            {
                rect = nextposition;
            }
            if (screenRect.Top > 0 && screenRect.Bottom < game.height && !game.ColidesWithLevel(boundingrect))
            {
                rect = nextposition;
            }
            ApplyGravity(gametime);
        }
        //метод що повертає новий прямокутник, в якому розміщений лише герой без лишнього
        private Rectangle GetBoundingRect(Rectangle rectangle)
        {
            int width = (int)(rect.Width * 0.55f);
            int x = rectangle.Left + (int)(rect.Width * 0.2f);
            return new Rectangle(x, rectangle.Top, width, rectangle.Height);
        }
        //Метод ходьби
        public void Run(bool SpriteRunLeft)
        {
            if (!isrunning)
            {
                isrunning = true;
                currentframe = 0;
                elapsedtime = 0;
                RunLeft = SpriteRunLeft;
            }
            iskillup = false;
            iskillrun = false;
            isdown = false;
        }
        //Метод зупинки
        public void Stop(bool SpriteStopLeft)
        {
            isrunning = false;
            iskillup = false;
            iskillrun = false;
            isdown = false;
            isStopLeft = SpriteStopLeft;
            currentframe = 0;
            elapsedtime = 0;
        }
        //Метод стрільби стоячи
        public void KillUp(bool SpriteKill)
        {
            if (!iskillup)
            {
                iskillup = true;
                currentframe = 0;
                elapsedtime = 0;
                KillUpLeft = SpriteKill;
            }
            iskillrun = false;
            isdown = false;
            isrunning = false;
        }
        //Метод стрільби в русі
        public void KillRun(bool SpriteKillRun)
        {
            if (!iskillrun)
            {
                iskillrun = true;
                currentframe = 0;
                elapsedtime = 0;
            }
            iskillup = false;
            isdown = false;
            isrunning = false;
            KillRunLeft = SpriteKillRun;
        }
        //Метод присідання
        public void Down(bool Spritedown)
        {
            if (!isdown)
            {
                isdown = true;
                currentframe = 0;
                elapsedtime = 0;
                downleft = Spritedown;
            }
            isrunning = false;
            iskillup = false;
            iskillrun = false;
        }
        // Метод стрільби в присідання
        public void DownKill(bool SpriteKillDown)
        {
            iskilldown = true;
            isrunning = false;
            iskillup = false;
            iskillrun = false;
            isdown = false;
            KillDownLeft = SpriteKillDown;
        }
        //метод коли герой пригає
        public void Jump(bool SpriteJumpLeft)
        {
            if (!isjumping)
            {
                isjumping = true;
                currentframe = 0;
                elapsedtime = 0;
                JumpLeft = SpriteJumpLeft;
                yVelocity = maxYVelocity;
            }
        }
        //метод гравітації та дії сили тяжіння на героя
        public void ApplyGravity(GameTime gametime)
        {
            yVelocity = yVelocity - g* gametime.ElapsedGameTime.Milliseconds/10;
            float dy = yVelocity * gametime.ElapsedGameTime.Milliseconds/10;

            Rectangle nextPosition = rect;
            nextPosition.Offset(0, -(int)(dy));
            Rectangle boundingrect = GetBoundingRect(nextPosition);

            Rectangle screenRect = Game1.GetScreenRect(boundingrect);

            if (screenRect.Top > 0 && screenRect.Bottom < game.height && !game.ColidesWithLevel(boundingrect))
                rect = nextPosition;
            bool ColideOnFallDown = (game.ColidesWithLevel(boundingrect) && yVelocity < 0);
            if (screenRect.Bottom > game.height || ColideOnFallDown)
            {
                yVelocity = 0;
                isjumping = false;
            }
        }
        // Метод малювання 
        public void Draw(SpriteBatch spritebatch)
        {
            Pos = new Vector2(0, -7);
            Rectangle r = new Rectangle(currentframe * framewidth, 0, framewidth, frameheight);
            SpriteEffects effects = SpriteEffects.None; 
            Rectangle screenRect = Game1.GetScreenRect(rect);
            spritebatch.Begin();
            //малювання героя коли він пригає
            if (isjumping)
            {
                isdown = false;
                iskillup = false;
                if (JumpLeft)
                {
                    Pos.X = 60;
                    effects = SpriteEffects.FlipHorizontally;
                    spritebatch.Draw(jump, screenRect, r, Color.White, 0, Pos, effects, 0);
                }
                else
                   
                    Pos.X = -60;
                spritebatch.Draw(jump, screenRect, r, Color.White, 0, Pos, effects, 0); 
            }
            else
            
            //малювання героя коли він стріляє стоячи
            if (iskillup)
            {
                if (KillUpLeft)
                {
                    Pos.X = 60;
                    effects = SpriteEffects.FlipHorizontally;
                    spritebatch.Draw(kill, screenRect, r, Color.White, 0, Pos, effects, 0);
                }
                else
                {
                    Pos.X = -60;
                    spritebatch.Draw(kill, screenRect, r, Color.White, 0, Pos, effects, 0);
                }
            }
            else
               
                    
                //малювання героя коли він присідає
                    if (isdown)
                    {
                        if (downleft)
                        {
                            Pos.X = 60;
                            effects = SpriteEffects.FlipHorizontally;
                            spritebatch.Draw(down, screenRect, r, Color.White, 0, Pos, effects, 0);
                        }
                        else
                        {
                            Pos.X = -60;
                            spritebatch.Draw(down, screenRect, r, Color.White, 0, Pos, effects, 0);
                        }
                    }else
           
                //малювання героя коли він іде стріляючи
                if (iskillrun)
                {

                    if (KillRunLeft)
                    {
                        Pos.X = 60;
                        effects = SpriteEffects.FlipHorizontally;
                        spritebatch.Draw(killrun, screenRect, r, Color.White, 0, Pos, effects, 0);
                    }
                    else
                    {
                        Pos.X = -60;
                        spritebatch.Draw(killrun, screenRect, r, Color.White, 0, Pos, effects, 0);
                    }

                }
                
                else

                    //малювання героя коли він просто іде вліво або право
                if (isrunning)
                {
                    Pos.X = -60;
                    if (RunLeft)
                    {
                        Pos.X = 60;
                        effects = SpriteEffects.FlipHorizontally;
                    }
                    spritebatch.Draw(run, screenRect, r, Color.White, 0, Pos, effects, 0);
                }
                else
                {
                    //малювання героя коли він зупиняється вліво або право
                    if (isStopLeft)
                    {
                        
                        Pos.X = 60;
                        effects = SpriteEffects.FlipHorizontally;
                        spritebatch.Draw(idle, screenRect, r, Color.White, 0, Pos, effects, 0);
                        
                    }
                    else
                    {
                        Pos.X = -60;
                        spritebatch.Draw(idle, screenRect, r, Color.White, 0, Pos, effects, 0);
                    
                    }
                }
                    spritebatch.End();
        }
    }
}
